package com.dfbz.dao.base;

import com.dfbz.annotation.MyField;
import com.dfbz.annotation.Table;
import com.dfbz.utils.JDBCUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;


/**
 * @author Administrator
 */
public class BaseDao<T> {
    /**
     * 添加
     * successful
    * */
    public void add(T t){
        Class<?> aClass = t.getClass();
        Table table = aClass.getDeclaredAnnotation(Table.class);
        String tableName = null;
        if (null != table){
            tableName = table.value();
        }
        Field[] fields = aClass.getDeclaredFields();
        StringBuilder sql = new StringBuilder();
        sql.append("insert into ").append(tableName).append(" values(");
        for (int i = 1; i <= fields.length; i++) {
            if (i == fields.length){
                sql.append("?").append(")");
            }else {
                sql.append("?").append(",");
            }
        }
        Connection conn = null;
        PreparedStatement psm = null;
        try {
            conn = JDBCUtil.getConnection();
            psm = conn.prepareStatement(sql.toString());
            int index = 1;
            for (Field field :fields) {
                String methodName = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
                Method method = aClass.getDeclaredMethod(methodName);
                Object invoke = method.invoke(t);
                psm.setObject(index,invoke);
                index++;
            }
            psm.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.close(null,psm,conn);
        }
    }

    /**
     * 删除
     *successful
     *
     * @param id
     * @param aClass
     * */
    public void delete(Object id, Class<T> aClass){
        Table table = aClass.getDeclaredAnnotation(Table.class);
        String tableName = null;
        String idName = null;
        if (null != table){
            tableName = table.value();
            idName = table.key();
        }
        String sql = "delete from " + tableName + " where " + idName + " = ?";

        Connection conn = null;
        PreparedStatement psm = null;

        try {
            conn = JDBCUtil.getConnection();
            psm = conn.prepareStatement(sql);
            psm.setObject(1,id);
            psm.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(null,psm,conn);
        }
    }

    /**
     * 获取
     * successful
     * */
    public T get(Object id, Class<T> aClass){
        Table table = aClass.getDeclaredAnnotation(Table.class);
        String tableName = null;
        String idName = null;
        if (null != table){
            tableName = table.value();
            idName = table.key();
        }
        String sql = "select * from " + tableName + " where " + idName + " = ?";
        Connection conn = null;
        PreparedStatement psm = null;
        ResultSet rs = null;
        T obj = null;
        try {
            conn = JDBCUtil.getConnection();
            psm = conn.prepareStatement(sql);
            psm.setObject(1,id);
            rs = psm.executeQuery();
            if (rs.next()){
                obj = aClass.newInstance();
                Field[] fields = aClass.getDeclaredFields();
                for (Field field : fields) {
                    String filedName = field.getName();
                    MyField myField = field.getDeclaredAnnotation(MyField.class);
                    if (null != myField){
                        filedName = myField.value();
                    }
                    String methodName = "set" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
                    Method method = aClass.getDeclaredMethod(methodName, field.getType());
                    method.invoke(obj,rs.getObject(filedName));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(null,psm,conn);
        }
        return obj;
    }

    /**
     * 更新
     * waiting
     * */
    public void update(T t) {
        Class<?> aClass = t.getClass();
        Table table = aClass.getDeclaredAnnotation(Table.class);
        String tableName = null;
        String idName = null;
        String idMethodName = null;
        if (null != table){
            tableName = table.value();
            idName = table.key();
            idMethodName = table.keyName();
        }
        StringBuilder sql = new StringBuilder();
        sql.append("update ").append(tableName).append(" set `").append(idName).append("` = ?,");
        Field[] fields = aClass.getDeclaredFields();
        try {
            for (Field field : fields) {
                String fieldName = field.getName();
                MyField myField = field.getDeclaredAnnotation(MyField.class);
                if (null != myField){
                    fieldName = myField.value();
                }
                if (!fieldName.equals(idName)){
                    String methodName = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
                    Method method = aClass.getDeclaredMethod(methodName);
                    Object obj = method.invoke(t);
                    if (null != obj){
                        sql.append(fieldName).append(" = ?,");
                    }
                }
            }
            sql.delete(sql.lastIndexOf(","),sql.length());
            sql.append(" where ").append(idName).append(" = ?");
            System.out.println("处理好的sql：" +  sql.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        Connection conn = null;
        PreparedStatement psm = null;
        try {
            int count = 0;
            conn = JDBCUtil.getConnection();
            psm = conn.prepareStatement(sql.toString());
            Method method = aClass.getDeclaredMethod(idMethodName);
            psm.setObject(++count,method.invoke(t));
            for (Field field : fields) {
                String fieldName = field.getName();
                MyField myField = field.getDeclaredAnnotation(MyField.class);
                if (null != myField){
                    fieldName = myField.value();
                }
                if (!fieldName.equals(idName)){
                    String methodName = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
                    Method getMethod = aClass.getDeclaredMethod(methodName);
                    Object obj = getMethod.invoke(t);
                    if (null != obj){
                        psm.setObject(++count,obj);
                    }
                }
            }
            psm.setObject(++count,method.invoke(t));
            psm.execute();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(null,psm,conn);
        }
    }
}
